package com.shoparc.shukhov;

import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import com.shoparc.shukhov.SGraph.Panel;
import com.shoparc.shukhov.SGraph.SVert;

import processing.core.*;
import javax.vecmath.*;

public class MyShukhov extends PApplet {

	public static void main(String args[]) {
		PApplet.main(new String[] { "--present",
				"com.shoparc.shukhov.MyShukhov" });
	}

	SGraph g;
	Boolean donemakinglines = false;
	Boolean doneconnecting = false;
	private Boolean doneShifting = false;
	Iterator<SVert> vertIterator;
	int flattenCount = 0;

	float currentZ = 0;

	public int w;
	public int h;
	public PFont defaultfont0 = createFont("ProggyCleanTTSZ", 50);
	// PFont defaultfont1 = createFont("ProggyCleanTTSZ", 9);

	public boolean mouseDragged;

	protected float Ctheta = (float) 180;
	protected float Czeta = (float) 0.06539816;
	protected PVector target = new PVector(0, 0, 0);
	PVector old_camera_pos = new PVector(-100, 0, -100);
	protected float zoom = 50;

	int MWHEEL;
	private boolean render = true;
	private boolean renderPleat = false;
	private boolean renderPanels = false;
	private boolean flattenPanels = false;

	void mouseWheel(int delta) {
		MWHEEL = delta;

	}

	public void setup() {

		size(1920, 1080, P3D);

		addMouseWheelListener(new java.awt.event.MouseWheelListener() {
			public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) {
				mouseWheel(evt.getWheelRotation());
			}
		});

		target = new PVector(-466, 110, 275);
		// target = new PVector(0,0,73);

		g = new SGraph(this);
		// g.initTest();

		// g.initRandom(12, 216, -693, -472, 73, 73, 6000, 2);

		// float spacing = 2;
		// int countx = (int) (Math.abs(216 - 12.53) / spacing);
		// int county = (int) (Math.abs(-693 + 353) / spacing);
		// g.initGrid(countx, county, 12.53f, 216.97f, -693.47f, -352.66f, 81f);

		ArrayList<Point3f> inPts = new ArrayList<Point3f>();
		try {
			inPts = g
					.inPts("C:/Users/cam/13workspace/shukhov/input/outPts.xml");

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		for (Point3f p : inPts) {
			g.addVert(p);

		}

		// g.connect(8.5f);
		// g.createLines(1600f);
		// g.fixEdges();

		try {
			g.inCtrls("C:/Users/cam/13workspace/shukhov/input/outCtrls.xml");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// g.fixPoints(8);

		vertIterator = g.verts.iterator();

		String[] fontList = PFont.list();
		PFont defaultfont2 = createFont(fontList[0], 50);
		textFont(defaultfont0);
		textSize(1.5f);

	}

	public void draw() {

		background(255);

		camVarUpdate();

		cameraControls(Ctheta, Czeta, target, zoom);

		if (!renderPanels) {
			if (!flattenPanels) {
				if (donemakinglines && !vertIterator.hasNext()) {
					g.update();
				} else {
					while (currentZ < 1250) {
						if (currentZ % 5 == 0) {
							g.contourFromPoints(currentZ);
						}
						currentZ += 10;
					}

					if (currentZ > 1200) {
						donemakinglines = true;
						g.pleat();
						g.createPanels();
					}

				}

				for (int i = 0; i < 100; i++) {
					if (vertIterator.hasNext()) {
						g.connect(vertIterator.next(), 7f);
					}
				}
				if (render) {
					g.render();
				}

				if (renderPleat) {
					g.renderPleat();
				}
			}
			if (flattenPanels) {
				if (flattenCount < g.panels.size()) {
					g.panels.get(flattenCount).flatten();
					g.renderPanels();
					flattenCount++;
				} else {
					flattenPanels = false;
				}
			}

		} else {
			g.renderPanels();

		}

		mouseDragged = false;

		controller();
	}

	private void controller() {
		if ((keyPressed) && (key == 'o')) {
			g.xmlOut();
		}
		if ((keyPressed) && (key == 'p')) {
			g.xmlLinesOut();
		}

		if ((keyPressed) && (key == '.')) {
			target.z -= 5;
		}
		if ((keyPressed) && (key == '/')) {
			target.z += 5;
		}
		if ((keyPressed) && (key == 's')) {
			g.shiftBottom();
		}
		if ((keyPressed) && (key == 'w')) {
			g.tightenHor();
		}
		if ((keyPressed) && (key == 'W')) {
			g.loosenHor();
		}
		if ((keyPressed) && (key == 'q')) {
			g.tightenVer();
		}
		if ((keyPressed) && (key == 'Q')) {
			g.loosenVer();
		}
		if ((keyPressed) && (key == 'e')) {
			g.shake();
		}

		if ((keyPressed) && (key == 'r')) {
			render = false;
		}
		if ((keyPressed) && (key == 'R')) {
			render = true;
		}
		if ((keyPressed) && (key == 't')) {
			renderPleat = false;
		}
		if ((keyPressed) && (key == 'T')) {
			renderPleat = true;
		}
		if ((keyPressed) && (key == 'G')) {
			renderPanels = true;
		}
		if ((keyPressed) && (key == 'g')) {
			renderPanels = false;
		}
		if ((keyPressed) && (key == 'b')) {
			flattenPanels = true;
		}

	}

	private void camVarUpdate() {
		if ((keyPressed) && (keyCode == KeyEvent.VK_ALT) && (mousePressed)) {
			if ((mouseX - pmouseX) > .5) {
				Ctheta += .03 * abs(mouseX - pmouseX);
			}
			if ((mouseX - pmouseX) < -.5) {
				Ctheta -= .03 * abs(mouseX - pmouseX);
			}
			if ((mouseY - pmouseY) > .5) {
				Czeta += .03 * abs(mouseY - pmouseY);
			}
			if ((mouseY - pmouseY) < -.5) {
				Czeta -= .03 * abs(mouseY - pmouseY);
			}
			if (Czeta > PI / 2)
				Czeta = (float) (PI / 2 - .001);
			if (Czeta < -PI / 2)
				Czeta = (float) (-PI / 2 + .001);

		}
		if (MWHEEL > 0) {
			zoom += 5;
		}
		if (MWHEEL < 0) {
			zoom -= 5;
		}
		MWHEEL = 0;
	}

	public void mouseDragged() {
		mouseDragged = true;
	}

	public void drawPersp() {
		camera();
		perspective();
	}

	public void drawOrtho() {
		camera();

		cameraControls(Ctheta, Czeta, target, zoom);
	}

	public void drawOrthoAlt() {

		camera();

		cameraControls(Ctheta, Czeta, target, zoom);
	}

	protected void cameraControls(float _Ctheta, float _Czeta, PVector _target,
			float _distance) {

		perspective(PI / 3, (float) 1.33, (height / 2) / tan(PI * 60 / 360)
				/ 100, (height / 2) / tan(PI * 60 / 360) * 10);

		// ortho(-zoom, zoom, -zoom, zoom, -1000, 1000);
		PVector camera_pos = new PVector(0, 0, 0);
		camera_pos.z = _distance * sin(_Czeta) + _target.z;
		float lil_d = (camera_pos.z - _target.z) / tan(_Czeta);
		camera_pos.x = lil_d * cos(_Ctheta) + _target.x;
		camera_pos.y = lil_d * sin(_Ctheta) + _target.y;
		camera(camera_pos.x, camera_pos.y, camera_pos.z, // eyeX, eyeY, eyeZ
				_target.x, _target.y, _target.z, // centerX, centerY, centerZ
				0, 0, -1);

	}

}
